home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / prgtools / mint / tw14w12s.zoo / tw14w12s / config.c next >
Encoding:
C/C++ Source or Header  |  1994-01-08  |  14.9 KB  |  811 lines

  1. /*
  2.  * Copyright 1992 Eric R. Smith. All rights reserved.
  3.  * Redistribution is permitted only if the distribution
  4.  * is not for profit, and only if all documentation
  5.  * (including, in particular, the file "copying")
  6.  * is included in the distribution in unmodified form.
  7.  * THIS PROGRAM COMES WITH ABSOLUTELY NO WARRANTY, NOT
  8.  * EVEN THE IMPLIED WARRANTIES OF MERCHANTIBILITY OR
  9.  * FITNESS FOR A PARTICULAR PURPOSE. USE AT YOUR OWN
  10.  * RISK.
  11.  */
  12. #include <ctype.h>
  13. #include <string.h>
  14. #include <osbind.h>
  15. #include <stdlib.h>
  16. #include "xgem.h"
  17. #include "toswin_w.h"
  18. #include "filbuf.h"
  19. #include "twdefs.h"
  20. #include "twproto.h"
  21.  
  22. #define LASTMENU ((MENU *)0)
  23.  
  24. #define QUOTE '\"'
  25. #define LINSIZ 256
  26. #define WORDSIZ 128
  27.  
  28.  
  29. char *
  30. nextword(ptr)
  31.     char **ptr;
  32. {
  33.     char *s, *start;
  34.  
  35.     s = *ptr;
  36.     while (*s && isspace(*s))
  37.         s++;
  38.     start = s;
  39.     if (*s == QUOTE) {
  40.         start++; s++;
  41.         while (*s && *s != QUOTE) s++;
  42.     } else {
  43.         while (*s && !isspace(*s))
  44.             s++;
  45.     }
  46.     if (*s)
  47.         *s++ = 0;
  48.     *ptr = s;
  49.     return start;
  50. }
  51.  
  52. int
  53. hexval(s)
  54.     char *s;
  55. {
  56.     int val = 0;
  57.     int c, i;
  58.  
  59.     for (i = 12; i >= 0; i -= 4) {
  60.         c = *s++;
  61.         c = toupper(c);
  62.         if (c >= '0' && c <= '9') {
  63.             val |= ((c - '0') << i);
  64.         } else if (c >= 'A' && c <= 'F') {
  65.             val |= ((c - 'A') + 10) << i;
  66.         } else {
  67.             break;
  68.         }
  69.     }
  70.     return val;
  71. }
  72.  
  73. char *
  74. valhex(i)
  75.     int i;
  76. {
  77.     static char sbuf[5];
  78.     char *s;
  79.     int c;
  80.  
  81.     for (s = &sbuf[3]; s >= sbuf; --s) {
  82.         c = i & 0x000f;
  83.         i = i >> 4;
  84.         if (c >= 0 && c <= 9) {
  85.             *s = c + '0';
  86.         } else {
  87.             *s = (c - 10) + 'A';
  88.         }
  89.     }
  90.     return sbuf;
  91. }
  92.  
  93. int
  94. decval(s)
  95.     char *s;
  96. {
  97.     int i = 0;
  98.     int c;
  99.  
  100.     while ((c = *s++)) {
  101.         if (c < '0' || c > '9') break;
  102.         i = 10 * i + (c - '0');
  103.     }
  104.     return i;
  105. }
  106.  
  107. char *
  108. valdec(i)
  109.     int i;
  110. {
  111.     static char foo[4];
  112.     char *s;
  113.     int d;
  114.  
  115.     s = foo;
  116.     if (i >= 0 && i < 1000) {
  117.         d = i / 100;
  118.         i = i % 100;
  119.         *s++ = '0'+d;
  120.         d = i / 10;
  121.         i = i % 10;
  122.         *s++ = '0'+d;
  123.         *s++ = '0'+i;
  124.     }
  125.     *s++ = 0;
  126.     return foo;
  127. }
  128.  
  129. /*
  130.  * like valdec, put strips leading '0' characters
  131.  */
  132.  
  133. char *
  134. valdec2(d)
  135.     int d;
  136. {
  137.     char *s;
  138.  
  139.     s = valdec(d);
  140.     while (*s == '0' && *(s+1) != 0)
  141.         s++;
  142.     return s;
  143. }
  144.  
  145. struct varstruct {
  146.     char *name;
  147.     int  *addr;
  148. } vars[] = {
  149.     "altcol", &altcol,
  150.     "altrow", &altrow,
  151.     "altscroll", &altscroll,
  152.     "align", &align_windows,
  153.     "appmenus", &appl_menus,
  154.     "autoclose", &autoclose,
  155.     "cut", &cut_options,
  156.     "defaultgadgets", &default_kind,
  157.     "environ", &env_options,
  158.     "flourishes", &win_flourishes,
  159. #ifdef WWA_AUTO_RAISE
  160.     "autoraise", &auto_raise,
  161. #endif
  162.     "paste", &paste_options,
  163.     "point", &point_to_type,
  164.     "showtool", &showtools,
  165.     "smoothscroll", &smoothscroll,
  166.     "stdcol", &stdcol,
  167.     "stdrow", &stdrow,
  168.     "stdscroll", &stdscroll,
  169.     0, 0
  170. };
  171.  
  172. /* adjust "font" and "height" to match (as closely as possible) a font
  173.  * setting in the global variable "fontdesc"; if a match can't be
  174.  * found, try the default font
  175.  */
  176.  
  177. static void
  178. adjust_font(font, height)
  179.     int *font, *height;
  180. {
  181.     FONTDESC *f, *dflt;
  182.     int i;
  183.  
  184.     dflt = 0;
  185.     f = fontdesc;
  186.     for (i = 0; i < gl_numfonts; i++) {
  187.         if (f->fontidx == *font && (f->points & (1L << *height)) )
  188.             return;        /* everything's OK */
  189.         else if (f->fontidx == default_font)
  190.             dflt = f;
  191.         f++;
  192.     }
  193.     *font = default_font;
  194.     if (dflt && (dflt->points & (1L << *height)))
  195.         return;        /* this height is OK */
  196.     *height = default_height;
  197. }
  198.  
  199. void
  200. set_default_font(s)
  201.     char *s;
  202. {
  203.     int font, size;
  204.  
  205.     font = hexval(nextword(&s));
  206.     size = hexval(nextword(&s));
  207.  
  208.     adjust_font(&font, &size);
  209.  
  210.     default_font = font;
  211.     default_height = size;
  212. }
  213.  
  214. static void
  215. adjust_xywh(xp, yp, wp, hp)
  216.     int *xp, *yp, *wp, *hp;
  217. {
  218.     int x = *xp;
  219.     int y = *yp;
  220.     int w = *wp;
  221.     int h = *hp;
  222.  
  223.     if (x + w > xdesk + wdesk) {
  224.         x = xdesk + wdesk - w;
  225.         if (x < xdesk) {
  226.             x = xdesk;
  227.             w = wdesk;
  228.         }
  229.     }
  230.     if (y + h > ydesk + hdesk) {
  231.         y = ydesk + hdesk - h;
  232.         if (y < ydesk) {
  233.             y = ydesk;
  234.             h = hdesk;
  235.         }
  236.     }
  237.     *xp = x; *yp = y;
  238.     *wp = w; *hp = h;
  239. }
  240.  
  241. void
  242. load_window(s)
  243.     char *s;
  244. {
  245.     int kind, flags, x, y, w, h, cols, rows, font, points;
  246.     int scroll;
  247.     char *title, *progname, *cmdlin, *progdir;
  248.     TEXTWIN *t;
  249.     WINDOW *v;
  250.  
  251.     flags = hexval(nextword(&s));
  252.     kind = hexval(nextword(&s));
  253.     x = hexval(nextword(&s));
  254.     y = hexval(nextword(&s));
  255.     w = hexval(nextword(&s));
  256.     h = hexval(nextword(&s));
  257.     cols = hexval(nextword(&s));
  258.     rows = hexval(nextword(&s));
  259.     font = hexval(nextword(&s));
  260.     points = hexval(nextword(&s));
  261.     title = nextword(&s);
  262.     progname = nextword(&s);
  263.     cmdlin = nextword(&s);
  264.     progdir = nextword(&s);
  265.     scroll = hexval(nextword(&s));
  266.  
  267.     adjust_font(&font, &points);
  268.     wind_calc(WC_BORDER, kind, x, y, w, h, &x, &y, &w, &h);
  269.     adjust_xywh(&x, &y, &w, &h);
  270.  
  271.     t = newproc(progname, cmdlin, progdir, x, y, cols, rows, scroll,
  272.             kind, font, points);
  273.     if (!t) return;
  274.     v = t->win;
  275.     wind_calc(WC_WORK, kind, x, y, w, h, &v->wi_x, &v->wi_y,
  276.         &v->wi_w, &v->wi_h);
  277.     title_window(v, title);
  278.     if (!oldACC)
  279.         open_window(v);
  280.     if (flags & WICONIFIED) {
  281.         iconify_win(v);
  282.     }
  283. }
  284.  
  285. extern int getfilename();
  286. static char config_name[128] = "TOSWIN.CNF";
  287. static char config_path[128];
  288.  
  289. void
  290. load_config(name)
  291.     char *name;
  292. {
  293.     FILBUF *f;
  294.     static char buf[LINSIZ];
  295.     char *s, *word;
  296.     struct varstruct *v;
  297.     ENTRY *e;
  298.     int *var;
  299.     int i;
  300.     int loadwins = 1;
  301.     int changepath = 1;
  302.  
  303.     if (!name) {            /* ask the user for a name */
  304.         name = buf;
  305.         i = getfilename(Strng(LOADCFG), name, config_path,
  306.                  config_name);
  307.         if (i != OK) return;
  308.         loadwins = 0;
  309.         changepath = 0;
  310.     }
  311.  
  312.     f = FBopen(name);
  313.     if (!f) return;
  314.  
  315.     graf_mouse(BEE, 0L);
  316.     while ((s = FBgets(f, buf, LINSIZ))) {
  317.         word = nextword(&s);
  318.         /* variable setting? */
  319.         for (v = vars; v->name; v++) {
  320.             if (!strcmp(v->name, word)) {
  321.                 word = nextword(&s);
  322.                 *v->addr = hexval(word);
  323.                 if (!strncmp(v->name, "std", 3))
  324.                     lineAset = 1;
  325.                 goto endloop;
  326.             }
  327.         }
  328.         if (!strcmp(word, "font")) {
  329.             set_default_font(s);
  330.         } else if (!strcmp(word, "path")) {
  331.             if (changepath)
  332.                 strcpy(progpath, nextword(&s));
  333.         } else if (!strcmp(word, "prog")) {
  334.             if (changepath)
  335.                 strcpy(dfltprog, nextword(&s));
  336.         } else if (!strcmp(word, "menu")) {
  337.             load_menu_key(s);
  338.         } else if (!strcmp(word, "win") && loadwins) {
  339.             load_window(s);
  340.         } else if (!strcmp(word, "tool") && loadwins) {
  341.             toolx = hexval(nextword(&s));
  342.             tooly = hexval(nextword(&s));
  343.             if (toolwindow && toolwindow->wi_handle >= 0) {
  344.                 close_window(toolwindow);
  345.                 toolwindow->wi_x = toolx;
  346.                 toolwindow->wi_y = tooly;
  347.                 open_window(toolwindow);
  348.             }
  349.         }
  350. endloop: ;
  351.     }
  352.  
  353. /* reset the global menu */
  354.     for (e = globalmenu->contents; e; e = e->next) {
  355.         if (e->func == toggle
  356. #ifdef GLOBL_APPL_MENUS
  357.          || e->func == togglemenu
  358. #endif
  359.         ) {
  360.             var = e->arg;
  361.             if (*var)
  362.                 check_entry(globalmenu, e);
  363.             else
  364.                 uncheck_entry(globalmenu, e);
  365.         }
  366.     }
  367.  
  368.     if (lineAset)
  369.         set_linea(stdcol, stdrow);
  370.     FBclose(f);
  371.     graf_mouse(ARROW, 0L);
  372. }
  373.  
  374. static int
  375. strwrite(fd, s)
  376.     int fd;
  377.     char *s;
  378. {
  379.     long r = strlen(s);
  380.  
  381.     return Fwrite(fd, r, s);
  382. }
  383.  
  384. static void
  385. strwritex(fd, s)
  386.     int fd;
  387.     char *s;
  388. {
  389.     strwrite(fd, s);
  390.     strwrite(fd, " ");
  391. }
  392.  
  393. static int
  394. quotewrite(fd, s)
  395.     int fd;
  396.     char *s;
  397. {
  398.     int nbytes;
  399.     char buf[WORDSIZ];
  400.     char c;
  401.  
  402.     buf[0] = QUOTE;
  403.     for (nbytes = 1; nbytes < WORDSIZ-2; nbytes++) {
  404.         c = *s++;
  405.         if (!c) break;
  406.         else if (c == QUOTE)
  407.             c = '\'';
  408.         buf[nbytes] = c;
  409.     }
  410.     buf[nbytes] = QUOTE;
  411.     return Fwrite(fd, (long)nbytes+1, buf);
  412. }
  413.  
  414. void
  415. save_config(file)
  416.     char *file;
  417. {
  418.     int fd, i;
  419.     struct varstruct *v;
  420.     static char name[128];
  421.     MENU *m;
  422.     ENTRY *e;
  423.     int savewins = 0;
  424.     WINDOW *w;
  425.     TEXTWIN *t;
  426.  
  427.     if (!file) {
  428.         file = name;
  429.         i = getfilename(Strng(SAVECFG), name, config_path,
  430.             config_name);
  431.         if (i != OK) return;
  432.         if (gl_winlist) {
  433.             i = form_alert(1, AlertStrng(SAVWPOS));
  434.             if (i == 1) savewins = 1;
  435.         }
  436.     }
  437.  
  438.     fd = Fcreate(file, 0);
  439.     if (fd <= 0) {
  440.         form_alert(1, AlertStrng(UNABLE1));
  441.         return;
  442.     }
  443.     for (v = vars; v->name; v++) {
  444.         if (!strncmp(v->name, "stdrow", 6)
  445.             || !strncmp(v->name, "stdcol", 6)) continue;
  446.         strwrite(fd, v->name);
  447.         strwrite(fd, " ");
  448.         strwrite(fd, valhex(*v->addr));
  449.         strwrite(fd, "\r\n");
  450.     }
  451.     if (lineAset) {
  452.         strwrite(fd, "stdcol "); strwrite(fd, valhex(stdcol));
  453.         strwrite(fd, "\r\nstdrow ");
  454.         strwrite(fd, valhex(stdrow));
  455.         strwrite(fd, "\r\n");
  456.     }
  457.     strwrite(fd, "font ");
  458.     strwritex(fd, valhex(default_font));
  459.     strwrite(fd, valhex(default_height)); strwrite(fd, "\r\n");
  460.  
  461.     if (*progpath) {
  462.         strwrite(fd, "path ");
  463.         strwrite(fd, progpath);
  464.         strwrite(fd, "\r\n");
  465.         if (*dfltprog) {
  466.             strwrite(fd, "prog ");
  467.             strwrite(fd, dfltprog);
  468.             strwrite(fd, "\r\n");
  469.         }
  470.     }
  471.  
  472.     strwrite(fd, "menu ");
  473.     for (m = sysbar; m != LASTMENU; m = m->next) {
  474.         for (e = m->contents; e; e = e->next) {
  475.             if (e->entry[0] != '-') {
  476.                 strwritex(fd, valhex(e->keycode));
  477.             }
  478.         }
  479.     }
  480.     strwrite(fd, "\r\n");
  481.  
  482.     if (savewins) {
  483.         strwrite(fd, "tool ");
  484.         strwritex(fd, valhex(toolx));
  485.         strwrite(fd, valhex(tooly));
  486.         strwrite(fd, "\r\n");
  487.  
  488.         for (w = gl_winlist; w; w = w->next) {
  489.             if (w->wtype != TEXT_WIN) continue;
  490.             t = w->extra;
  491.             strwrite(fd, "win ");
  492.             strwritex(fd, valhex(w->flags));
  493.             if (w->flags & WICONIFIED) {
  494.                 strwritex(fd, valhex(w->old_wkind));
  495.                 strwritex(fd, valhex(w->prevx));
  496.                 strwritex(fd, valhex(w->prevy));
  497.                 strwritex(fd, valhex(w->prevw));
  498.                 strwritex(fd, valhex(w->prevh));
  499.             } else {
  500.                 strwritex(fd, valhex(w->wi_kind));
  501.                 strwritex(fd, valhex(w->wi_x));
  502.                 strwritex(fd, valhex(w->wi_y));
  503.                 strwritex(fd, valhex(w->wi_w));
  504.                 strwritex(fd, valhex(w->wi_h));
  505.             }
  506.             strwritex(fd, valhex(NCOLS(t)));
  507.             strwritex(fd, valhex(NROWS(t)));
  508.             strwritex(fd, valhex(t->cfont));
  509.             strwritex(fd, valhex(t->cpoints));
  510.             quotewrite(fd, w->wi_title); strwrite(fd, " ");
  511.             strwritex(fd, t->prog);
  512.             quotewrite(fd, t->cmdlin); strwrite(fd, " ");
  513.             strwritex(fd, t->progdir);
  514.             strwrite(fd, valhex(SCROLLBACK(t)));
  515.             strwrite(fd, "\r\n");
  516.         }
  517.     }
  518.  
  519.     (void)Fclose(fd);
  520. }
  521.  
  522.  
  523. /*
  524.  * menu configuration routines
  525.  */
  526.  
  527. void
  528. load_menu_key(s)
  529.     char *s;
  530. {
  531.     MENU *m;
  532.     ENTRY *e;
  533.  
  534.     m = sysbar;
  535.     e = m->contents;
  536.     for(;;) {
  537.         if (e->entry[0] != '-') {
  538.             e->keycode = hexval(nextword(&s));
  539.         }
  540.         e = e->next;
  541.         if (!e) {
  542.             m = m->next;
  543.             if (m == LASTMENU) break;
  544.             e = m->contents;
  545.         }
  546.     }
  547.     show_menu(sysbar);
  548. }
  549.  
  550. void
  551. config_menu()
  552. {
  553.     int r;
  554.     int x, y, w, h;
  555.     int dummy, mx, my, keycode;
  556.     int done, event, mbreturn;
  557.     int atstart = 1;
  558.     MENU *m, *lastm;
  559.     ENTRY *e, *laste;
  560.     int change;
  561.  
  562.     wind_update(BEG_MCTRL);
  563.     form_center(menudef_dialog, &x, &y, &w, &h);
  564.     form_dial(FMD_START, 0, 0, 32, 32, x, y, w, h);
  565.     if (win_flourishes)
  566.         form_dial(FMD_GROW, 0, 0, 32, 32, x, y, w, h);
  567.  
  568.     objc_draw(menudef_dialog, 0, 1, x, y, w, h);
  569.  
  570.     lastm = 0; laste = 0;
  571.     m = sysbar;
  572.     e = m->contents;
  573.     done = 0;
  574.     change = 1;
  575.  
  576.     do {
  577.         if (change) {
  578.             if (atstart) {
  579.                 if (menudef_dialog[MDPREV].ob_state != DISABLED)
  580.                     objc_change(menudef_dialog, MDPREV, 0,
  581.                         x, y, w, h, DISABLED, 1);
  582.             } else {
  583.                 if (menudef_dialog[MDPREV].ob_state != NORMAL)
  584.                     objc_change(menudef_dialog, MDPREV, 0,
  585.                         x, y, w, h, NORMAL, 1);
  586.             }
  587.             if (e->next == 0 && m->next == LASTMENU) {
  588.                 if (menudef_dialog[MDNEXT].ob_state != DISABLED)
  589.                     objc_change(menudef_dialog, MDNEXT, 0,
  590.                         x, y, w, h, DISABLED, 1);
  591.             } else {
  592.                 if (menudef_dialog[MDNEXT].ob_state != NORMAL)
  593.                     objc_change(menudef_dialog, MDNEXT, 0,
  594.                         x, y, w, h, NORMAL, 1);
  595.             }
  596.             menudef_dialog[MENUSTR].ob_spec = (long)m->title;
  597.             menudef_dialog[ENTRYSTR].ob_spec = (long)e->entry;
  598.             menudef_dialog[ASCIISTR].ob_spec = (long)UNALT(e->keycode);
  599.             menudef_dialog[HEXSTR].ob_spec = (long)valhex(e->keycode);
  600.  
  601.             objc_draw(menudef_dialog, MENUFRAM, 2, x, y, w, h);
  602.             objc_draw(menudef_dialog, KEYFRAM, 2, x, y, w, h);
  603.         }
  604.         change = 0;
  605.  
  606.         event = evnt_multi(MU_BUTTON|MU_KEYBD,
  607.             0x0002, 0x0001, 0x0001,
  608.             0, 0, 0, 0, 0,
  609.             0, 0, 0, 0, 0,
  610.             0L, 0L,
  611.             &mx, &my, &dummy, &dummy,
  612.             &keycode, &mbreturn);
  613.  
  614.         if (event & MU_KEYBD) {
  615.             change = 1;
  616.             if ((keycode & 0x00ff) == ' ')
  617.                 e->keycode = 0;
  618.             else if (keycode == 0x1c0d) {
  619.         /* RETURN key pressed -- exit dialog */
  620.                 done = 1;
  621.             } else {
  622.                 e->keycode = keycode;
  623.             }
  624. #if 0
  625.             if (!(event & MU_BUTTON))
  626.                 goto advance;
  627. #endif
  628.         }
  629.         if (event & MU_BUTTON) {
  630.             r = objc_find(menudef_dialog, 0, 2, mx, my);
  631.             if (r == MDNEXT || r == MDPREV) {
  632.                 if (menudef_dialog[r].ob_state == DISABLED) {
  633.                     continue;
  634.                 }
  635.                 evnt_timer(50L);
  636.             }
  637.             switch (r) {
  638.             case MDNEXT:
  639.         advance:
  640.                 atstart = 0;
  641.                 if (e->next) {
  642.                     e = e->next;
  643.                 } else if (m->next != LASTMENU) {
  644.                     m = m->next;
  645.                     e = m->contents;
  646.                 } else if (event & MU_KEYBD) {
  647.                     done = 1;
  648.                 } else {
  649.                     (void)Bconout(2, 7);
  650.                 }
  651.                 if (e->entry[0] == '-')
  652.                     goto advance;
  653.                 change = 1;
  654.                 break;
  655.             case MDPREV:
  656.         retreat:
  657.                 if (atstart) {
  658.                     (void)Bconout(2, 7);
  659.                 } else {
  660.                     if (m->contents == e) {
  661.                         laste = 0;
  662.                         if (sysbar == m)
  663.                             lastm = 0;
  664.                         else {
  665.                             lastm = sysbar;
  666.                             while (m != lastm->next)
  667.                                 lastm = lastm->next;
  668.                         }
  669.                     } else {
  670.                         lastm = m;
  671.                         laste = m->contents;
  672.                         while (laste->next != e)
  673.                             laste = laste->next;
  674.                     }
  675.  
  676.                     m = (lastm) ? lastm : sysbar;
  677.                     if (laste)
  678.                         e = laste;
  679.                     else
  680.                         for (e = m->contents; e->next; )
  681.                             e = e->next;
  682.                 }
  683.                 if (m == sysbar && e == m->contents)
  684.                     atstart = 1;
  685.                 if (e->entry[0] == '-') goto retreat;
  686.                 change = 1;
  687.                 break;
  688.             case MDDONE:
  689.                 done = 1; break;
  690.             default:
  691.                 (void)Bconout(2, 7);
  692.             }
  693.         }
  694.     } while (!done);
  695.  
  696.     if (win_flourishes)
  697.         form_dial(FMD_SHRINK, 0, 0, 32, 32, x, y, w, h);
  698.     form_dial(FMD_FINISH, 0, 0, 32, 32, x, y, w, h);
  699.     wind_update(END_MCTRL);
  700.     show_menu(sysbar);
  701. }
  702.  
  703. /*
  704.  * loadable menu support:
  705.  * loadmenu(fname): load the .MNU file corresponding to the program 'fname'
  706.  */
  707.  
  708. void
  709. sendhex(s)
  710.     char *s;
  711. {
  712.     WINDOW *w;
  713.     static char pbuf[5];
  714.     char *t;
  715.     int i, c;
  716.  
  717.     if (!gl_topwin) return;
  718.     w = gl_topwin;
  719.  
  720.     i = 0; t = pbuf;
  721.  
  722.     for(;;) {
  723.         if (!*s) break;
  724.         *t++ = *s++;
  725.         i++;
  726.         if (i == 4) {
  727.             c = hexval(pbuf);
  728.             if (!c) break;
  729.             i = 0;
  730.             t = pbuf;
  731.             (*w->keyinp)(w, c, 0);
  732.         }
  733.     }
  734. }
  735.  
  736. MENU *
  737. loadmenu(fname)
  738.     char *fname;
  739. {
  740.     static char pname[LINSIZ];
  741.     char *s, *lastdot, c;
  742.     FILBUF *f;
  743.     MENU *bar, *m, **last;
  744.     int keycode;
  745.     char *name, *data;
  746.  
  747. #ifndef GLOBAL_APPL_MENUS
  748. /* appl_menus now controls whether to load menus at all */
  749.     if (!appl_menus)
  750.         return 0;
  751. #endif
  752.     s = pname;
  753.     while (*s++ = *fname++) ;
  754.     --s;
  755.  
  756.     lastdot = s;
  757.     while (s >= pname && (c = *s) != '\\') {
  758.         if (c == '.') lastdot = s;
  759.         --s;
  760.     }
  761.  
  762.     *lastdot++ = '.';
  763.     *lastdot++ = 'M'; *lastdot++ = 'N'; *lastdot++ = 'U';
  764.     *lastdot = 0;
  765.  
  766.     f = FBopen(pname);
  767.     if (!f) return 0;
  768.  
  769.     last = &bar;
  770.     bar = m = 0;
  771.     for(;;) {
  772.         if (!FBgets(f, pname, LINSIZ)) break;
  773.         s = pname;
  774.         if (!isspace(*s)) {
  775.             m = create_menu(pname);
  776.             if (!m) break;
  777.             *last = m;
  778.             last = &m->next;
  779.         } else {
  780.             while (*s && isspace(*s)) s++;
  781.             if (!*s) continue;
  782.             name = strdup(nextword(&s));
  783.             data = strdup(nextword(&s));
  784.             keycode = hexval(nextword(&s));
  785.             if (name[0] == '-')
  786.                 add_entry(m, name, sendhex, data, keycode, DISABLED);
  787.             else
  788.                 add_entry(m, name, sendhex, data, keycode, NORMAL);
  789.         }
  790.     }
  791.     FBclose(f);
  792.     return bar;
  793. }
  794.  
  795. void
  796. unloadmenu(men)
  797.     MENU *men;
  798. {
  799.     ENTRY *e;
  800.     MENU *m;
  801.  
  802.  
  803.     for (m = men; m; m = m->next) {
  804.         for (e = m->contents; e; e = e->next) {
  805.             if (e->arg)
  806.                 free(e->arg);
  807.         }
  808.     }
  809.     destroy_menu(men);
  810. }
  811.